package org.komarichin.jdo.dao;

import org.apache.commons.collections.CollectionUtils;
import org.komarichin.beans.IUser;
import org.komarichin.beans.dao.IUserDAO;
import org.komarichin.jdo.persistence.Role;
import org.komarichin.jdo.persistence.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.jdo.support.JdoDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import javax.jdo.JDOHelper;
import javax.jdo.Query;
import java.util.Collection;
import java.util.HashSet;

/**
 * User: Michael Komarichin
 * Date: 05.10.2009
 * Time: 10:34:32
 */
@Transactional(readOnly = true)
public class UserDAO extends JdoDaoSupport implements IUserDAO {
    private static final long serialVersionUID = 4187138052912210328L;
    private static final Logger log = LoggerFactory.getLogger(UserDAO.class);

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public IUser save(IUser user) {
        log.debug("save#user : {}", user);
        return (IUser) getJdoTemplate().makePersistent(user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void remove(IUser user) {
        log.debug("remove#user : {}", user);
        getJdoTemplate().deletePersistent(JDOHelper.getObjectId(user.getId()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void update(IUser user) {
        log.debug("update#user : {}", user);
        getJdoTemplate().makePersistent(user);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser login(String login, String password) {
        log.debug("login#name : {}, password : {}", login, password);
        Collection result = getJdoTemplate().find(User.class, "login == loginValue && password == passwordValue",
                "String loginValue, String passwordValue", new String[]{login, password});
        log.debug("result : {}", result);
        return result != null && result.size() > 0 ? (IUser) CollectionUtils.get(result, 0) : null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser findByName(String login) {
        log.debug("findByName#login : {}", login);
        Collection result = getJdoTemplate().find(User.class, "login == value", "String value", new String[]{login});
        log.debug("result : {}", result);
        return result != null && result.size() > 0 ? (IUser) CollectionUtils.get(result, 0) : null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public Collection<IUser> getAllowUsers(Long permission) {
        log.debug("getAllowUser#permission : {}", permission);
        Query query = getPersistenceManager().newQuery(Role.class, "permission >= pPermission");
        query.declareParameters("Long pPermission");
        query.setResult("id");
        Collection<Long> ids = (Collection<Long>) query.execute(permission);

        query = getPersistenceManager().newQuery(User.class, "role == pRoleIds");
        query.declareParameters("Long pRoleIds");
        Collection<IUser> result = new HashSet<IUser>();
        for (Long id : ids) {
            result.addAll((Collection<? extends User>) query.execute(id));
        }
        log.debug("result : {}", result);
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    public Role getUserRole(IUser user) {
        log.debug("getUserRole#user : {}", user);
        Query query = getPersistenceManager().newQuery(User.class, "login == pUserLogin");
        query.setResult("role");
        query.declareParameters("String pUserLogin");
        Collection<Long> result = (Collection<Long>) query.execute(user.getLogin());
        log.debug("result : {}", result);
        return result != null && result.size() > 0 ? (Role) getJdoTemplate().getObjectById(Role.class, CollectionUtils.get(result, 0)) : null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public Collection<IUser> getAll() {
        log.debug("getAll");
        Collection<IUser> users = getJdoTemplate().find(User.class);
        log.debug("result : {}", users);
        return users;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser newInstanceUser(Long id, String login, String password, String hint) {
        log.debug("newInstanceUser#id : {}, login : {}, password : {}, hint : {}",
                new Object[]{id, login, password, hint});
        return new User(null, login, password, hint, null);
    }    
}
